﻿#region Copyright Info

// 
// Majesty of Omega - The next evolution of macro management space strategy
// 
// Copyright 2007-2009 André Claaßen
// 
// This file is protected by the terms and conditions of the
// Microsoft Community License (Ms-CL 1.1), a copy of which should
// have been distributed along with this software. If not,
// you may find the license information at the following URL:
// 
// http://www.microsoft.com/resources/sharedsource/licensingbasics/communitylicense.mspx

#endregion

#region

using System;
using Majesty_of_Omega.Config;

#endregion

namespace Majesty_of_Omega.Model.Research
{
    /// <summary>
    /// A Research item is an abstract technology field, 
    /// with a relative percentage value for spending research points
    /// </summary>
    /// <remarks>
    /// This abstraction is needed, to provide an equal interface to the various
    /// research objects for the WPF.
    /// </remarks>
    [Serializable]
    public abstract class ResearchItem
    {
        /// <summary>
        /// The id of the researach item. The ID is normally a 2 Digit string, which is build of the Type_ID field of a 
        /// <see cref="TechSchool" /> or a <see cref="TechField" />.
        /// </summary>
        /// <remarks>
        /// This type id is used, to reconstruct the association to the tech field or tech school after 
        /// deserialization (loading) the research item out of a stream
        /// </remarks>
        private readonly string researchItemTypeID;

        /// <summary>
        /// Initializes a new instance of the <see cref="ResearchItem"/> class.
        /// </summary>
        protected ResearchItem(string typeID)
        {
            researchItemTypeID = typeID;
            ResearchPercentage = 0;
        }

        /// <summary>
        /// The id of the researach item. The ID is normally a 2 Digit string, which is build of the Type_ID field of a 
        /// <see cref="TechSchool" /> or a <see cref="TechField" />.
        /// </summary>
        /// <remarks>
        /// This type id is used, to reconstruct the association to the tech field or tech school after 
        /// deserialization (loading) the research item out of a stream
        /// </remarks>
        public string ResearchItemTypeID
        {
            get { return researchItemTypeID; }
        }

        /// <summary>
        /// Retrieves a formatted string info of the current research for the Technology field info part.
        /// </summary>
        /// <value>The current research formatted.</value>
        public string CurrentResearchFormatted
        {
            get
            {
                return String.Format("{0} %  {1} RP",
                                     this.ResearchPercentage,
                                     this.ResearchPoints);
            }
        }

        /// <summary>
        /// Gets the research done formatted.
        /// </summary>
        /// <value>The research done formatted.</value>
        public string ResearchDoneFormatted
        {
            get
            {
                return String.Format("{0} %", this.ProgressInCurrentLevel);
            }
        }

        /// <summary>
        /// Gets or sets the relative research percentage of the research item .
        /// </summary>
        /// <value>The research percentage.</value>
        public int ResearchPercentage { get; set; }

        /// <summary>
        /// Gets or sets the research points.
        /// </summary>
        /// <value>The research points.</value>
        public virtual int ResearchPoints { get; set; }

        /// <summary>
        /// Gets the progress in current level in percent.
        /// </summary>
        /// <remarks>
        /// 70% means, that you must research 30% to enter the next level.
        /// </remarks>
        /// <value>The progress in current level.</value>
        public abstract int ProgressInCurrentLevel { get; }

        /// <summary>
        /// Gets the icon of this research item.
        /// </summary>
        /// <value>The icon.</value>
        abstract public string Icon
        { 
            get;
        }

        /// <summary>
        /// Gets the tech level of this research item
        /// </summary>
        /// <value>The tech level.</value>
        public virtual int TechLevel
        {
            get 
            {
                throw new NotImplementedException();
            }
            set 
            {
                throw new NotImplementedException();
            }
        }

        #region equality functions

        /// <summary>
        /// Equalses the specified obj.
        /// </summary>
        /// <param name="obj">The obj.</param>
        /// <returns></returns>
        public bool Equals(ResearchItem obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            return Equals(obj.researchItemTypeID, researchItemTypeID) && obj.ResearchPercentage == ResearchPercentage;
        }

        /// <summary>
        /// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>.
        /// </summary>
        /// <param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>.</param>
        /// <returns>
        /// true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
        /// </returns>
        /// <exception cref="T:System.NullReferenceException">
        /// The <paramref name="obj"/> parameter is null.
        /// </exception>
        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != typeof (ResearchItem)) return false;
            return Equals((ResearchItem) obj);
        }

        /// <summary>
        /// Serves as a hash function for a particular type.
        /// </summary>
        /// <returns>
        /// A hash code for the current <see cref="T:System.Object"/>.
        /// </returns>
        public override int GetHashCode()
        {
            unchecked
            {
                return ((researchItemTypeID != null ? researchItemTypeID.GetHashCode() : 0)*397) ^ ResearchPercentage;
            }
        }

        #endregion
    }
}